package com.example.aop;

import com.alibaba.fastjson.JSONObject;
import com.example.mapper.OperateLogMapper;
import com.example.pojo.OperateLog;
import com.example.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * 记录用户对数据库的操作
 */

@Slf4j
@Aspect
@Component
public class LogAspect {

    @Autowired
    private OperateLogMapper operateLogMapper;
    @Autowired
    private HttpServletRequest httpServletRequest;
    @Around("@annotation(com.example.aop.Log)")
    public Object recordlog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("日志打印......");
        //创建一个日志对象
        OperateLog operateLog = new OperateLog();

        //利用令牌获取 操作人id
        String jwt = httpServletRequest.getHeader("token");
        Integer id = (Integer) JwtUtils.parseJwt(jwt).get("id");
        //获取操作人id
        operateLog.setOperateUser(id);

        //获取操作时间
        operateLog.setOperateTime(LocalDateTime.now());

        //获取操作名
        operateLog.setClassName(proceedingJoinPoint.getClass().getName());

        //获取方法名
        operateLog.setMethodName(proceedingJoinPoint.getSignature().getName());

        //获取方法运行参数
        operateLog.setMethodParams(Arrays.toString(proceedingJoinPoint.getArgs()));

        //运行开始
        Long begin = System.currentTimeMillis();

        //运行原始数据 获取返回值
        Object result = proceedingJoinPoint.proceed();

        //运行结束 计算耗时
        Long end = System.currentTimeMillis();
        operateLog.setCostTime(end - begin);

        //将返回值对象转json形式的String
        String jsonString = JSONObject.toJSONString(result);
        operateLog.setReturnValue(jsonString);

        //调用mapper插入数据库
        operateLogMapper.insert(operateLog);
        return result;

    }

}
